#include <string.h>
#include <stdio.h>
#include <stdlib.h>




#include "bloom_filter.h"

/**
 * Test whether filter1 is a subfilter of filter2
 * 
 */
 
int is_subfilter(bloom_filter_t filter1, bloom_filter_t filter2) 
{ 
    int i; 
    for(i = 0; i<sizeof(bloom_filter_t); i++) { 
        if ((filter1[i] | filter2[i] ) != filter1[i]) { 
            return 0; 
        }
    }
    return 1; 
}

/**
 * Add the value of filter2 into filter1
 */
void add_bloom_filter(bloom_filter_t filter1, bloom_filter_t filter2) 
{
    int i; 
    for(i=0; i<sizeof(bloom_filter_t); i++) { 
        filter1[i] |= filter2[i]; 
    } 
}

/**
 * Copy the value of filter2 into filter1
 * 
 */
void copy_bloom_filter(bloom_filter_t filter1, bloom_filter_t filter2) 
{
    int i; 
    for(i=0; i<sizeof(bloom_filter_t); i++) { 
        filter1[i] = filter2[i]; 
    }
}
/**
 * Initalize an empty bloom filter; 
 */
 
void init_bloom_filter(bloom_filter_t filter) 
{
    bzero(&filter[0], sizeof(bloom_filter_t)); 
}    

static char byte_to_char(int byte) 
{
    if (byte >= 0 && byte <= 9) {
        return '0' + byte; 
    } else if (byte >= 10 && byte < 16) { 
        return 'A' + (byte - 10); 
    } else { 
        fprintf(stderr, "out of range value %d\n", byte); 
        exit(-1); 
    }
}    

static int char_to_byte(char ch) 
{ 
    if (ch >= '0' && ch <= '9') { 
        return ch - '0'; 
    } else if (ch >= 'A' &&  ch <= 'F') { 
        return ch - 'A' + 10; 
    } else { 
        fprintf(stderr, "out of rang char %c\n", ch); 
        exit(-1); 
    }
}

void bloom_filter_to_hex_string(bloom_filter_t filter, char * buf, int buf_size) 
{
    int i; 
    int byte;
    char ch; 
    int len = 0; 
    for(i=0; i<sizeof(bloom_filter_t); i++)  { 
        byte = (filter[i] & 0xF0) >> 4; 
        buf[len++] =  byte_to_char(byte); 
        byte = filter[i] & 0x0F; 
        buf[len++] = byte_to_char(byte); 
    }                    
    buf[len++] = '\0'; 
}

void hex_string_to_bloom_filter(char * buf,  bloom_filter_t filter) 
{
    int i ; 
    int byte; 
    int size = strlen(buf);     
    init_bloom_filter(filter); 
    for(i=0; i<size; i++) { 
        if (i % 2 == 0) { 
            byte = char_to_byte(buf[i]) << 4; 
        } else { 
            byte = char_to_byte(buf[i]); 
        }
        filter[i/2] |= byte; 
        if (i/2 >= sizeof(bloom_filter_t)) { 
            break; 
        }
    }        
} 
    
